import random
import json
import datetime

from django.http.response import JsonResponse
from django.core.cache import cache
from django.utils import timezone

from trend.apis import get_ffk3
from trend.models import Result
from trend.functions import get_ffk3_trend_data_range, get_ffk3_piece_trend_data_range

from utils.response import paginate_queryset
from utils.cache import rate_limit_lock


# Create your views here.


def ffk3_trend(request):
    data = get_ffk3()[0]
    random.seed(data['uniqueIssueNumber'])

    return JsonResponse({
        'data': {
            'num': data['uniqueIssueNumber'],
            'value': sum(map(int, data['openCode'].split(','))) & 1,
            'predict': random.randint(0, 1)
        }
    })



def ffk3_mult_conn(request):
    _type = request.GET.get('type', 'ds')
    choices = request.GET.get('choices', '')
    choices = [int(n) for n in choices.split(',') if n]
    page = request.GET.get('page', '0')
    cur = request.GET.get('cur', 'false')
    data = Result.ffk3.today()
    today = timezone.localdate().isocalendar()
    if _type == 'all': types = ['ds', 'dx']
    else: types = [_type]

    limit =100
    if page == 'all': limit =1000
    
    @rate_limit_lock()
    def process_data(_d, _is, _t, _cho, _p):
        objects = list(data.order_by('issue_id'))

        res = []

        for group in range(limit):
            s = today.year
            s = s * 100 + today.week
            s = s * 100 + today.weekday
            s = s * 100 + group % 100
            if page =='all': s = s * 10 + group // 100
            else: s = s * 10 + int(page)

            for _type in types:
                random.seed(s)
                nxt = None
                conn = 0
                last = None
                row = {'now': False}

                for obj in objects:
                    if _type == 'ds': value = obj.singular
                    else: value = obj.large
                    if last != (nxt == value):
                        if conn in choices:
                            res.append({**row})
                        last = nxt == value
                        conn = 0
                    conn += 1
                    row['value'] = value
                    row['predict'] = nxt
                    row['conn'] = conn
                    row['last'] = last
                    row['group']= group % 100 + 1
                    row['page'] = group // 100 + 1
                    row['num'] = int(obj.issue_id) % 10000
                    row['type'] = _type
                    nxt = row['next_predict'] = random.randint(0, 1)

                row['now'] = True
                if row['conn'] in choices:
                    res.append({**row})
        
        return res
    
    res = process_data(today.weekday, data.first().issue_id, _type, request.GET.get('choices', ''), page)
    if cur == 'true':
        res = [
            row for row in res if row['now']
        ]
    return JsonResponse({
        'total': len(res),
        'rows': res
    })



def ffk3_mult_conn_piece(request):
    _type = request.GET.get('type', 'ds')
    choices = request.GET.get('choices', '')
    choices = [int(n) for n in choices.split(',') if n]
    page = request.GET.get('page', 0)
    group = int(request.GET.get('group', 0))

    data = Result.ffk3.today()
    today = timezone.localdate().isocalendar()

    @rate_limit_lock()
    def process_piece(_d, _is, _t, _cho, _p, _g):
        objects = list(data.order_by('issue_id'))
        res = []
        s = today.year
        s = s * 100 + today.week
        s = s * 100 + today.weekday
        s = s * 100 + group % 100
        s = s * 10 + int(page)
        random.seed(s)
        nxt = None
        conn = 0
        last = None
        row = {'now': False}
        for obj in objects:
            if _type == 'ds': value = obj.singular
            else: value = obj.large
            if last != (nxt == value):
                if conn in choices:
                    res.append({**row})
                last = nxt == value
                conn = 0
            conn += 1
            row['value'] = value
            row['predict'] = nxt
            row['conn'] = conn
            row['last'] = last
            row['group']= group % 100 + 1
            row['page'] = int(page) % 10 + 1
            row['num'] = int(obj.issue_id) % 10000
            row['type'] = _type
            nxt = row['next_predict'] = random.randint(0, 1)

        row['now'] = True
        if row['conn'] in choices:
            res.append({**row})
        
        return res
    
    res = process_piece(today.weekday, data.first().issue_id, _type, request.GET.get('choices', ''), page, group)

    return JsonResponse({
        'total': len(res),
        'rows': res
    })


def cache_ffk3_mult_conn(request):
    res = get_ffk3_trend_data_range(gte=13)
    return JsonResponse({
        'count': len(res),
        'rows': res
    })


def ffk3_conn_feat(request):
    feat = request.GET.get('feat', '')
    gte = request.GET.get('gte', '0')
    lte = request.GET.get('lte', '100')

    data = cache.get(f'TREND:FFK3:PRED:FEAT:{feat}:{gte}:{lte}:LIST')
    data = data or '[]'
    res = json.loads(data)
    return JsonResponse({
        'count': len(res),
        'rows': res
    })

    gte, lte = int(gte), int(lte)

    res = []
    for group in range(1000):
        for _type in ['ds', 'dx']:
            data = get_ffk3_piece_trend_data_range(group, _type, gte, lte, False)

            N = len(feat)
            M = len(data)
            for i in range(M - N + 1):
                for j, fn in enumerate(feat):
                    row = data[i + j]
                    tag = fn[0]
                    num = int(fn[1:])
                    if tag == 'g' and row['conn'] >= num:
                        pass
                    elif tag == 'l' and row['conn'] <= num:
                        pass
                    else:
                        break
                else:
                    res.append({
                        'group': group % 100 + 1,
                        'page': group // 100 + 1,
                        'type': _type,
                        **row,
                    })

    return JsonResponse({
        'count': len(res),
        'rows': res
    })